package com.qiche.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.qiche.aspect.Result;
import com.qiche.common.ResponseCode;
import com.qiche.config.YmlConfig;
import com.qiche.enums.ResultEnum;
import com.qiche.mapper.LuckyDrawLogMapper;
import com.qiche.mapper.LuckyDrawMapper;
import com.qiche.model.Card;
import com.qiche.model.LuckyDraw;
import com.qiche.model.LuckyDrawLog;
import com.qiche.model.PrizeItem;
import com.qiche.model.PrizeItemVo;
import com.qiche.model.Product;
import com.qiche.model.StoreMember;
import com.qiche.model.Voucher;
import com.qiche.model.VoucherRepository;
import com.qiche.service.CardService;
import com.qiche.service.LuckyDrawLogService;
import com.qiche.service.LuckyDrawService;
import com.qiche.service.PrizeItemService;
import com.qiche.service.ProductService;
import com.qiche.service.StoreMemberService;
import com.qiche.service.VoucherRepositoryService;
import com.qiche.service.VoucherService;
import com.qiche.util.ApplicationUtils;
import com.qiche.util.LuckyDrawUtil;

import tk.mybatis.mapper.entity.Example;

/**
 * Created by Linzw on 2018/01/24.
 */
@Service("luckyDrawService")
public class LuckyDrawServiceImpl extends BaseService<LuckyDraw> implements LuckyDrawService {

	@Resource
	private LuckyDrawMapper luckyDrawMapper;

	@Resource
	public LuckyDrawLogMapper luckyDrawLogMapper;

	@Autowired
	public PrizeItemService prizeItemService;

	@Autowired
	private VoucherRepositoryService repositoryService;

	@Autowired
	public LuckyDrawLogService luckyDrawLogService;

	@Autowired
	private VoucherService voucherService;

	@Autowired
	private CardService cardService;

	@Autowired
	private YmlConfig ymlConfig;

	@Autowired
	private ProductService productService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Result<?> luckyDraw(Long merchantId, StoreMember storeMember, Integer ifLuckyDraw) throws Exception {
		List<LuckyDrawLog> luckyDrawLog = null;
		LuckyDraw luckyDraw = selectByMerchantId(merchantId.intValue());
		List<PrizeItemVo> prizeItemVos = prizeItemService.selectByLuckyDrawId(luckyDraw.getId());

		int dayDrawCount = getLuckyDrawDay(luckyDraw, merchantId, storeMember.getId().intValue());
		// 验证
		Result<?> result = luckyDrawVerify(luckyDraw, luckyDrawLog, merchantId, storeMember.getId().intValue(),
				prizeItemVos, dayDrawCount);
		if (result.getCode() == ResponseCode.ERROR.getCode() || result.getCode() == 4012 || result.getCode() == 4013) {
			return result;
		}
		List<PrizeItem> prizeItems = prizeItemService.selectByLuckyDrawId(luckyDraw.getId().longValue());
		Map<String, Object> map = new HashMap<>();
		if (ifLuckyDraw == 1) {
			if (prizeItems.size() <= 0) {
				map.put("dayDrawCount", 0);
			} else {
				map.put("dayDrawCount", dayDrawCount);
			}
			map.put("prizeItems", prizeItemVos);
			map.put("luckyDrawRule", luckyDraw.getLuckyDrawRule());
			return Result.createBySuccess(map);
		}

		List<Double> probList = new ArrayList<Double>();
		probList.add(luckyDraw.getPercentage());
		probList.add(1 - luckyDraw.getPercentage());
		if (LuckyDrawUtil.draw(probList) > 0) {
			PrizeItem prizeItem = null;
			for (PrizeItemVo prizeItemVo : prizeItemVos) {
				if (prizeItemVo.getPrizeName().equals("未中奖")) {
					prizeItem = new PrizeItem();
					prizeItem.setPrizeName(prizeItemVo.getPrizeName());
					prizeItem.setId(prizeItemVo.getId());
					prizeItem.setPrizeCount(prizeItemVo.getPrizeCount());
					prizeItem.setLuckyDrawId(prizeItemVo.getLuckyDrawId());
					prizeItem.setCardId(prizeItemVo.getCardId());
					map.put("luckyDrawItem", prizeItem);
				}
			}
			int insert = insertLuckyDrawLog(merchantId, storeMember.getId().intValue(), prizeItem, luckyDraw.getId());
			map.put("prizeItems", prizeItemVos);
			map.put("dayDrawCount", dayDrawCount - 1);
			map.put("luckyDrawRule", luckyDraw.getLuckyDrawRule());
			map.put("prizeType", 0);
			return Result.createBySuccess(map);
		}
		// 已中奖
		if (prizeItems.size() <= 0) {
			map.put("prizeItems", prizeItemVos);
			map.put("luckyDrawRule", luckyDraw.getLuckyDrawRule());
			map.put("dayDrawCount", 0);
			return Result.createByError("奖品已发完，谢谢回顾！", map);
		}
		Random rand = new Random();
		int num = rand.nextInt(prizeItems.size());
		if (prizeItems.get(num).getPrizeCount() == 0) {
			map.put("prizeItems", prizeItemVos);
			map.put("luckyDrawRule", luckyDraw.getLuckyDrawRule());
			map.put("dayDrawCount", 0);
			return Result.createByError("奖品已发完，谢谢回顾！", map);
		}
		grantLuckyDraw(num, merchantId, storeMember, prizeItems.get(num), luckyDraw.getId());
		PrizeItem prizeItem = prizeItems.get(num);
		PrizeItem item = new PrizeItem();
		item.setId(prizeItem.getId());
		item.setCardId(prizeItem.getCardId());
		item.setLuckyDrawId(prizeItem.getLuckyDrawId());
		item.setPrizeCount(prizeItem.getPrizeCount());
		item.setPrizeName(prizeItem.getPrizeName());
		item.setUpdateTime(prizeItem.getUpdateTime());
		item.setCreateTime(prizeItem.getCreateTime());
		item.setId(prizeItem.getId());
		map.put("dayDrawCount", dayDrawCount - 1);// 今天剩余多少抽取次数
		map.put("prizeItems", prizeItemVos);
		map.put("luckyDraw", 0);// 是否中奖 0:不中奖 1:中奖
		map.put("luckyDrawItem", item);
		map.put("prizeType", 1);
		map.put("luckyDrawRule", luckyDraw.getLuckyDrawRule());
		return Result.createBySuccess(map);
	}

	private void grantLuckyDraw(int prizeCount, Long merchantId, StoreMember storeMember, PrizeItem prizeItem,
			Integer luckyDrawId) throws Exception {
		PrizeItem updatePrizeItem = new PrizeItem();
		updatePrizeItem.setId(prizeItem.getId());
		updatePrizeItem.setPrizeCount(prizeItem.getPrizeCount() - 1);
		int PrizeCount = prizeItemService.updatePrizeCount(updatePrizeItem);

		int insert = insertLuckyDrawLog(merchantId, storeMember.getId().intValue(), prizeItem, luckyDrawId);
		if (prizeItem.getPrizeType() == 2 || prizeItem.getPrizeType() == 3) {
			// Card card = cardService.selectById(prizeItem.getCardId());
			Card card = new Card();
			if (prizeItem.getPrizeType() == 2) {
				Product product = productService.selectById(prizeItem.getCardId());
				card.setCardAmount(product.getPrice().longValue());
				card.setCardTitle(product.getName());
			} else {
				card.setCardTitle(prizeItem.getModelName());
				card.setStatus("1");
				card.setCardAmount(0L);
			}
			card.setCustomerId(storeMember.getId());
			card.setCustomerPhone(storeMember.getPhone());
			card.setCardCode(ymlConfig.getQicheSystemCardPrefix() + ApplicationUtils.getRandomString(16));
			card.setAvailable("周一,周二,周三,周四,周五,周六,周日");
			card.setCardType("service");
			card.setMerchantId(merchantId);
			card.setStatus("1");
			card.setVerifyBeginDate(new Date()); // 当前时间为可核销开始时间
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.MONTH, Integer.valueOf(prizeItem.getProductEffective()));// 根据产品的有效期来定
			card.setVerifyEndDate(calendar.getTime());
			card.setCreateDate(new Date());
			cardService.save(card);
		} else {
			// 代金卷
			VoucherRepository repository = repositoryService.selectByKey(prizeItem.getVoucherId());
			Voucher voucher = new Voucher();
			voucher.setAgentId(repository.getAgentId());
			voucher.setTitle(repository.getName());
			voucher.setAmount(repository.getAmount());
			voucher.setStoreMemberId(storeMember.getId().intValue());
			voucher.setMerchantId(repository.getMerchantId());
			voucher.setIndefinite(repository.getIndefinite());
			voucher.setDueTime(repository.getDueTime());
			voucher.setCode(ApplicationUtils.getRandomString(25));
			voucher.setIsWriteoff(0);
			voucherService.save(voucher);
		}
		if (PrizeCount == 0 && insert == 0) {
			throw new RuntimeException("抽奖入库异常");
		}
	}

	private int insertLuckyDrawLog(Long merchantId, Integer storeMemberId, PrizeItem prizeItem, Integer luckyDrawId) {
		LuckyDrawLog luckyDrawLog = new LuckyDrawLog();
		luckyDrawLog.setLuckyDrawId(luckyDrawId);
		luckyDrawLog.setMerchantId(merchantId.intValue());
		if (prizeItem.getPrizeType() == 2) {
			luckyDrawLog.setCardId(prizeItem.getCardId().intValue());
		}
		luckyDrawLog.setPrizeName(prizeItem.getPrizeName());
		luckyDrawLog.setStoreMemberId(storeMemberId);
		luckyDrawLog.setCreateTime(new Date());
		luckyDrawLog.setUpdateTime(new Date());
		int insert = luckyDrawLogMapper.insert(luckyDrawLog);
		return insert;
	}

	private Result<?> luckyDrawVerify(LuckyDraw luckyDraw, List<LuckyDrawLog> luckyDrawLog, Long merchantId,
			Integer storeMemberId, List<PrizeItemVo> prizeItemVos, int dayDrawCount) throws Exception {
		Map<String, Object> map = new HashMap<>();
		Long date = new Date().getTime();
		map.put("prizeItems", prizeItemVos);
		map.put("dayDrawCount", 0);
		map.put("luckyDrawRule", luckyDraw.getLuckyDrawRule());
		if (date < luckyDraw.getStartTime().getTime()) {
			return Result.createByResultEnum(ResultEnum.ACTIVITY_START, map);
		}
		if (date > luckyDraw.getEndTime().getTime()) {
			return Result.createByResultEnum(ResultEnum.ACTIVITY_END, map);
		}
		luckyDrawLog = luckyDrawLogService.queryLuckyDrawLog(luckyDraw, merchantId, storeMemberId);
		if (luckyDraw.getLuckyDrawLimit() == 2) {
			List<LuckyDrawLog> LuckyDrawLogList = luckyDrawLogService.selectByLuckyDrawId(luckyDraw.getId());
			if (LuckyDrawLogList.size() >= luckyDraw.getOverallLuckyDraw()) {
				return Result.createByError("总抽奖次数已经用完", map);
			}
		}
		if (luckyDrawLog.size() >= luckyDraw.getLuckyDrawDay()) {
			return Result.createByError("您当天的抽奖已用完", map);
		}
		return Result.createBySuccess();
	}

	private int getLuckyDrawDay(LuckyDraw luckyDraw, Long merchantId, Integer storeMemberId) throws Exception {
		List<LuckyDrawLog> luckyDrawLog = luckyDrawLogService.queryLuckyDrawLog(luckyDraw, merchantId, storeMemberId);
		return luckyDraw.getLuckyDrawDay() - luckyDrawLog.size();
	}

	@Override
	public LuckyDraw selectByMerchantId(Integer merchantId) {
		LuckyDraw luckyDraw = null;
		Example example = new Example(LuckyDraw.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("merchantId", merchantId);
		List<LuckyDraw> luckyDraws = selectByExample(example);
		if (luckyDraws != null && luckyDraws.size() > 0) {
			luckyDraw = luckyDraws.get(0);
		}
		return luckyDraw;
	}

	@Transactional
	@Override
	public int insertResultId(LuckyDraw luckyDraw) {
		PrizeItem prizeItem = new PrizeItem();
		prizeItem.setCreateTime(new Date());
		prizeItem.setPrizeName("未中奖");
		prizeItem.setPrizeCount(0);
		prizeItem.setCardId(0l);
		luckyDrawMapper.insertResultId(luckyDraw);
		prizeItem.setLuckyDrawId(Long.parseLong(luckyDraw.getId().toString()));
		return prizeItemService.save(prizeItem);
	}
}
